import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RunDbrd {
    public static int threadNum = 8;
    public static int topN = 1000;
    public static int trainingSizeTemp = 200;
    // 需要在代码中设置好结果的目录
    public static String ResultsDic;
    public static int progress = 0;
    public static int iteration = 100;

    public static void main(String[] args) {
        String currentProjectName = args[0];
        String classicalOrRealistic = args[1];

        System.out.println("currentProjectName = " + currentProjectName);
        System.out.println("classicalOrRealistic = " + classicalOrRealistic);

        String reportsLargeTxtDic = "./" + currentProjectName + "/reportsLargeDic";

        System.out.println("reportsLargeTxtDic = " + reportsLargeTxtDic);

        ExecutorService prepareThreadsPool = Executors.newFixedThreadPool(threadNum);

        File folder = new File(reportsLargeTxtDic);
        File[] listOfFiles = folder.listFiles();
        System.out.println("Size of " + listOfFiles.length);
        for (int i = 0; i < listOfFiles.length; i = i + 1) {
            try {
                File currentFile = listOfFiles[i];
                String nameStr = currentFile.getName();
                String[] splits = nameStr.split("_");

                int startID = Integer.parseInt(splits[1]);

                int endID = Integer.parseInt(splits[2]);

                int trainingTarget = Integer.parseInt(splits[0].split("-")[1]);

                String command = "";
                if (classicalOrRealistic.equalsIgnoreCase("c")) {
                    ResultsDic  = "./" + currentProjectName + "/RandomPreviousResearch100";

                    command = "./fast-dbrd -k "
                            + topN + " --training-duplicates "
                            + trainingSizeTemp + " -i 1 -n  "
                            + trainingTarget + "Titles --recommend "
                            + ResultsDic + "/" + trainingTarget + "_"
                            + startID + "_" + endID + "_" + trainingSizeTemp + "_"
                            + startID + "_" + endID + "_" + "Results -r "
                            + "./full-textual-full-categorial.cfg "
                            + reportsLargeTxtDic + "/id-" + trainingTarget + "_"
                            + startID + "_" + endID + "_" + "-reports-large.txt";
                } else if (classicalOrRealistic.equalsIgnoreCase("r")) {
                    ResultsDic  = "./" + currentProjectName + "/RandomRealistic100_200";

                    command = "./fast-dbrd -k "
                            + topN + " --training-duplicates "
                            + trainingSizeTemp + " -i 1 -n  "
                            + trainingTarget + "Titles --recommend "
                            + ResultsDic + "/" + trainingTarget + "_"
                            + startID + "_" + endID + "_" + trainingSizeTemp + "_"
                            + startID + "_" + endID + "_" + "Results -r "
                            + "./full-textual-full-categorial.cfg "
                            + reportsLargeTxtDic + "/id-" + trainingTarget + "_"
                            + startID + "_" + endID + "_" + "-reports-large.txt";
                }

                if (command.equalsIgnoreCase("")) {
                    System.err.println("command为空");
                }

                System.err.println("Running Command :" + command);

//              public DataPrepareThread(String command, int trainingTarget, int startID, int endID, String reportsLargeTxtDic) {
                DataPrepareThread dataPrepareThread = new DataPrepareThread(command, trainingTarget, startID, endID, reportsLargeTxtDic);
                prepareThreadsPool.execute(dataPrepareThread);

            } catch (Exception e) {
                System.err.println("报异常：" + e);
                System.err.println("文件名：" + listOfFiles[i].getName());
            }

        }

        prepareThreadsPool.shutdown();
        while (!prepareThreadsPool.isTerminated()) {
            try {
                Thread.sleep(9000L);
            } catch (Throwable throwable) {

            }
        }
        System.err.println("Finished all prepare Threads");

        System.err.println("Finished all threads");

    }
}

class DataPrepareThread extends Thread {
    String command;
    int trainingTarget;
    int startID;
    int endID;
    String reportsLargeTxtDic;

    public DataPrepareThread(String command, int trainingTarget, int startID, int endID, String reportsLargeTxtDic) {
        this.command = command;
        trainingTarget = trainingTarget;
        startID = startID;
        endID = endID;
        reportsLargeTxtDic = reportsLargeTxtDic;
    }

    @Override
    public void run() {
        executeCommand();
    }

    public void executeCommand() {


        System.err.println("Running Command :" + command);
        executeCommand(command);

        System.gc();

        System.err.println("Simplging a file");

        parseResultsFile(new File(RunDbrd.ResultsDic + "/"
                + trainingTarget + "_" + startID + "_" + endID + "_"
                + RunDbrd.trainingSizeTemp + "_" + startID + "_" + endID + "_"
                + "Results"));

        System.err.println("Delete file ,,, " + RunDbrd.ResultsDic + "/"
                + trainingTarget + "_" + startID + "_" + endID + "_"
                + RunDbrd.trainingSizeTemp + "_" + startID + "_" + endID + "_"
                + "Results");

        // 原作者的：删除原始的Results文件，每个Result文件只保留剩下的topN个
        deleteFile(RunDbrd.ResultsDic + "/" + trainingTarget + "_"
                + startID + "_" + endID + "_" + RunDbrd.trainingSizeTemp + "_"
                + startID + "_" + endID + "_" + "Results");

        System.err.println(reportsLargeTxtDic + "/id-" + trainingTarget + "_"
                + startID + "_" + endID + "_" + "-reports-large.txt");

        deleteFile(reportsLargeTxtDic + "/id-" + trainingTarget + "_"
                + startID + "_" + endID + "_" + "-reports-large.txt");

        RunDbrd.progress++;
        System.err.println("Total Done is " + RunDbrd.progress
                + " , Percentage: % " + ((double) RunDbrd.progress)
                / ((double) RunDbrd.iteration));

    }

    public String executeCommand(String command) {

        StringBuffer output = new StringBuffer();

        Process p;
        try {
            p = Runtime.getRuntime().exec(command);
            p.waitFor();
            // BufferedReader dd=new BufferedReader(new
            // InputStreamReader(p.getInputStream()));
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    p.getInputStream()));

            // InputStreamReader streamReader= new
            // InputStreamReader(p.getInputStream());
            String line = "";
            while ((line = reader.readLine()) != null) {
                System.out.println(line + "\n");
            }

            System.err.println("Done with Command : " + command);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return output.toString();

    }

    public void parseResultsFile(File filePath) {

        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = " ";
        Boolean rangeIsCorrect = false;
        long overallCount = 0;
        String[] searchToGet = filePath.getName().split("_");
        double searchSpaceSize = Double.parseDouble(searchToGet[0]) + 2;

        boolean startOnlyDuplicates = true;

        File simpleFile = null;
        FileWriter writer = null;
        boolean notFoundYet = true;
        try {
            File file = filePath;
            String[] names = file.getName().split("_");

            File folder = new File(RunDbrd.ResultsDic + "Simple/");
            if (!folder.exists()) {
                if (folder.mkdir()) {
                    System.out.println("Directory is created!");
                } else {
                    System.out.println("Failed to create directory!");
                }
            }

            simpleFile = new File(RunDbrd.ResultsDic + "Simple/"
                    + filePath.getName());
            writer = new FileWriter(simpleFile, false);

            if (file.exists()) {
                // System.out.println("File is found successfully...");
            }
            br = new BufferedReader(new FileReader(file));

            short count = 0;

            boolean OneIteration = false;

            String orgLine = null;
            while ((line = br.readLine()) != null) {

                orgLine = line;
                line = line.trim().replaceAll(" +", " ");
                line = line.trim().replaceAll("= ", "=");

                // System.out.println("~ "+line);
                String[] values = line.split(cvsSplitBy);

                // System.out.println(line);
                if (values[0] == null || line.trim().length() == 0) {
                    continue;
                }
                if (values[0].equals("Iteration")) {

                    if (OneIteration) {
                        break;
                    }
                    OneIteration = true;
                    continue;
                }

                if (values[0].equals("Retrieving")) {

                    if (values[2].equals("non-duplicate")) {
                        notFoundYet = false;
                    } else if (values[2].equals("duplicate")) {
                        notFoundYet = true;
                        startOnlyDuplicates = false;

                    }

                    if (startOnlyDuplicates) {
                        notFoundYet = true;
                    }

                    if (notFoundYet) {
                        writer.append(orgLine + "\n");
                    }

                    // System.out.println("Working on Bug Iteration " +
                    // (++overallCount));
                    count = 0;

                } else if (notFoundYet) {

                    writer.append(orgLine + "\n");

                    ++count;

                    if (RunDbrd.topN == count) {
                        writer.append("\n");

                        notFoundYet = false;
                    }
                }

                writer.flush();
                // }

                // System.gc();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public void deleteFile(String fileName) {

        File f = null;
        boolean bool = false;

        try {
            // create new file
            f = new File(fileName);

            // tries to delete a non-existing file
            bool = f.delete();

            // prints
            System.out.println("File deleted: " + bool);

            // creates file in the system
            f.createNewFile();

            // createNewFile() is invoked
            System.out.println("createNewFile() method is invoked");

            // tries to delete the newly created file
            bool = f.delete();

            // print
            System.out.println("File deleted: " + bool);

        } catch (Exception e) {
            // if any error occurs
            // e.printStackTrace();
        }
    }

}
